package com.sgq.vue.service.system.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.sgq.vue.dao.system.UserMapper;
import com.sgq.vue.dao.resource.CityMapper;
import com.sgq.vue.entity.system.Role;
import com.sgq.vue.dao.system.RoleMapper;
import com.sgq.vue.entity.system.User;
import com.sgq.vue.entity.resource.City;
import com.sgq.vue.service.system.RoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sgq.vue.utils.system.MenuTree;
import com.sgq.vue.vo.query.RoleQueryVo;
import com.sgq.vue.vo.query.resource.RoleCityVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author SGQ
 * @since 2023-10-30
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private CityMapper cityMapper;

    @Override
    public IPage<Role> findRoleListByUserId(IPage<Role> page, RoleQueryVo roleQueryVo) {

        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.like(!ObjectUtils.isEmpty(roleQueryVo),Role::getRoleName,roleQueryVo.getRoleName());

        queryWrapper.orderByAsc(Role::getId);

        //根据用户ID查询用户信息
        User user = userMapper.selectById(roleQueryVo.getUserId());
        //如果用户不为空、且不是管理员，则只能查询自己创建的角色
        if(user != null && !ObjectUtils.isEmpty(user.getIsAdmin()) && user.getIsAdmin() != 1){
            queryWrapper.eq(Role::getCreateBy,roleQueryVo.getUserId());
        }

        return baseMapper.selectPage(page,queryWrapper);

    }

    /**
     * 保存角色权限关系
     *
     * @param roleId
     * @param permissionIds
     * @return
     */
    @Override
    @Transactional
    public boolean saveRolePermission(Long roleId, List<Long> permissionIds) {
        //删除该角色对应的权限信息
        baseMapper.deleteRolePermission(roleId);
        //保存角色权限
        return baseMapper.saveRolePermission(roleId,permissionIds) > 0 ;
    }

    @Override
    public boolean check(Long roleId) {
        int count = roleMapper.selectRoleMappingUsers(roleId);
        return count > 0 ? true :false;
    }

    @Override
    @Transactional
    public boolean removeRoleAndRelationship(Long roleId) {
        //删除当前角色
        int count = this.baseMapper.deleteById(roleId);
        //删除角色所有的映射权限关系
        roleMapper.deleteRolePermission(roleId);

        return count == 1 ? true : false;
    }

    /**
     * 根据用户ID查询该用户拥有的角色ID
     *
     * @param userId
     * @return
     */
    @Override
    public List<Long> findRoleIdByUserId(Long userId) {
        return this.baseMapper.findRoleIdByUserId(userId);
    }

    /**
     *  为角色分配城市
     * @param userId
     * @param roleId
     * @return
     */
    @Override
    @Cacheable(cacheNames = "cityTree", key = "'userId'+ #userId")
    public RoleCityVo findCityWeatherTree(Long userId, Long roleId) {
        //1.查询当前用户信息 （当前用户已经拥有的城市）
        User user = userMapper.selectById(userId);
        List<City> list = null;
        //2.判断当前用户角色，如果是管理员，则查询所有权限；如果不是管理员，则只查询自己所拥有的的权限
        if(!ObjectUtils.isEmpty(user.getIsAdmin()) && user.getIsAdmin() == 1){
            //查询所有城市
            list = cityMapper.selectList(null);
        }else{
            //根据用户ID查询
            list = cityMapper.selectCityListByUserId(userId);
        }

        System.out.println("list = " + list.size());
        //3.组装成树数据（根据用户权限多少不同获得不同的菜单树结构）
        List<City> cityTree = MenuTree.makeCityTree(list, 10000L);
        //4.查询要分配角色的原有城市（被分配角色原本已拥有的城市）
        List<City> cities = cityMapper.selectCityListByRoleId(roleId);
        //5.找出该角色存在的数据
        List<Long> listIds = new ArrayList<Long>();
        Optional.ofNullable(list).orElse(new ArrayList<>())
                .stream()
                .filter(Objects::nonNull) //等同于 obj -> obj!=null
                .forEach(item -> {
                    Optional.ofNullable(cities).orElse(new ArrayList<>())
                            .stream()
                            .filter(Objects::nonNull)
                            .forEach(obj ->{
                                if(item.getId().equals(obj.getId())){
                                    listIds.add(obj.getId());
                                    return;
                                }
                            });
                });
        //创建
        RoleCityVo vo = new RoleCityVo();
        vo.setCityList(cityTree);
        vo.setCheckList(listIds.toArray());
        return vo;
    }

    /**
     *  保存角色与城市的关系
     * @param roleId
     * @param cityIds
     * @return
     */
    @Override
    public boolean saveRoleCity(Long roleId, List<Long> cityIds) {
        cityMapper.deleteByRoleId(roleId);
        Integer count = cityMapper.saveRoleCity(roleId,cityIds);
        return count == cityIds.size() ? true : false;
    }




}
